'''
    为了对查询参数进行额外的校验，可以导入 Query 库
    Query 支持多种校验
'''
import uvicorn
from fastapi import Query, FastAPI
from typing import Optional, List, Tuple, Dict

app = FastAPI()


# 可选参数有默认值 + 长度最大为10
@app.get("/items")
async def read_items(name: Optional[str] = Query(default=None, max_length=10)):
    results = {"items": [{"items_id": "Foo"}, {"item_id": "Bar"}]}
    if name:
        results.update({"name": name})
    return results


'''
    name: Optional[str] = Query(None) 等价于  name: Optional[str] = None
'''


# 一个参数多个校验

@app.get('/items/twice')
async def read_items2(name: Optional[str] = Query(default=None, min_length=3, max_length=10)):
    return {"name": name}


# 正则表达式
@app.get("/items/regular")
async def read_items3(
        name: Optional[str] = Query(
            default=None,
            min_length=3,
            max_length=10,
            regex="^lx.*q$"
        )):
    return {"name": name}


'''
    不使用 Query 时，查询参数怎么必传？
    不指定默认值就行
    
    当使用 Query 时，查询参数怎么必传？
    Query 默认值参数 default 是必传的，传了默认值不就变成可选参数了吗，那怎么办呢？
    Query(default=..., )
'''


# 必传参数
@app.get("/items/required")
async def read_items4(name: Optional[str] = Query(default=..., max_length=10)):
    return {"name": name}


# List 类型的查询参数
@app.get("/list")
async def read_item(address: Optional[List[str]] = Query([], max_length=2)):
    return {"addr": address}


'''
    http://127.0.0.1:8000/list?address=a&address=b&address=c  不会报错
    
    max_length 对数组长度并不生效， 但是对数组中元素的长度有效

'''


# List 类型的查询参数有多个默认值
@app.get('/list/default')
async def read_item(addr: Optional[List[str]] = Query(["gz", "sz"])):
    return {"addr": addr}


'''
     不传参的请求结果     {
    "addr": [
        "gz",
        "sz"
    ]
}


'''



# 元数据
# Query 可以添加元数据相关信息，这些信息将包含在生成的 OpenAPI 中，并由文档用户界面和外部工具使用

'''
    四种元数据参数
    # 别名
    alias: Optional[str] = None
    
    # 标题
    title: Optional[str] = None
    
    # 描述
    description: Optional[str] = None
    
    # 是否弃用
    deprecated: Optional[bool] = None 
'''



if __name__ == '__main__':
    uvicorn.run(app="main:app", host="127.0.0.1", port=8000, reload=True, debug=True)
